home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Archive / Graphics / QuickDraw GX / GX->PostScript Sample / GXToPostScript / Imaging Engine / WorkSpace.c < prev   
Encoding:
C/C++ Source or Header  |  2000-09-28  |  5.0 KB  |  179 lines  |  [TEXT/MPS ]

  1. /*
  2.      File:        WorkSpace.c
  3.  
  4.      Contains:    QuickDraw GX to PostScript conversion code.
  5.                          File contains routines to allocate and deallocate the
  6.                         Imaging Engine workspaces.
  7.           
  8.                          Routines include:
  9.                                 PSReleaseWorkSpace                         
  10.                                 PSSetWorkSpaceSize    
  11.  
  12.      Version:    Technology:    Quickdraw GX 1.1.x
  13.       
  14.      Copyright:    © 1990-1997 by Apple Computer, Inc., all rights reserved.
  15. */
  16.  
  17. #include <MacMemory.h>
  18. #include "Private.h"
  19. #include "IOUtilities.h"
  20.  
  21. #ifdef resumeLabel
  22.     #undef resumeLabel
  23. #endif
  24. #define resumeLabel(exception)
  25.  
  26.  
  27. /*************************************************************
  28.     The following routines control the size of the workspace.
  29.     The workspace is a handle that hangs off of our globals which we
  30.     use for pointers that we must pass to gx graphics so we can get shape data.
  31.     
  32.     The workspace is resized to be as big as wee need it.  It's size is
  33.     set back to zero if it was bigger than the maximum persistant threshold.
  34.     That way, outlying large requests are not left around.
  35.     
  36.     Additionally, when not in use, the handle is purgeable.  That we we
  37.     are not a total pig.
  38.     
  39.     The proper way to use the workspace is as follows:
  40.     
  41.                 status = PSSetWorkSapceSize(hGlobals, neededSize);
  42.                 workHandle = (*hGlobals)->hWorkSpace;                        // Get current workspace handle
  43.                 //Do some work with the workspace, copy glyph data in etc…
  44.                 …
  45.                 …
  46.                 status = PSReleaseWorkSpace(hGlobals);
  47.                 
  48.     Actually, there is an array of workspaces.
  49.       This is to allow nested use of the workspace.
  50.         This can be necessitated by recursive text face styles.
  51.         Example:  Glyph shape (which uses workspace) has a text face
  52.                                 which has a style which has a pattern which has a
  53.                                 shape which is a glyph or a bitmap (which uses workspace) and so on.
  54.                                 
  55.                 
  56. ********************************************************************/
  57.  
  58. //<FF>
  59. /***************************************************
  60.     Routine PSSetWorkSpaceSize:
  61.     
  62.     Routine makes sure that our current workspace is big enough
  63.     for whatever we need to do.  Used in place of NewHandle, or NewPtr.
  64.     
  65.     hGlobals:        Handle to our globals.
  66.     newSize:        How much space we need.
  67.     
  68. ****************************************************/
  69. OSErr PSSetWorkSpaceSize(TIEGlobalsHdl hGlobals, long newSize)
  70.     {
  71.         OSErr                                            status = noErr;    
  72.         register TIEGlobalsPtr        pGlobals;
  73.         Handle                                        aHandle;
  74.         long                                            currSize;
  75.         Handle                                        *workSpaceArray;
  76.         
  77.         pGlobals = *hGlobals;
  78.                 
  79.         require((pGlobals->workSpaceIndex < pGlobals->params.gsaveLimit), workSpaceToDeep);
  80.         
  81.         workSpaceArray = (Handle*)((long)pGlobals + pGlobals->offsetToWorkspace);
  82.         
  83.         /** Make sure handle at this level has been allocated **/
  84.         
  85.         if (workSpaceArray[pGlobals->workSpaceIndex] == nil) {
  86.         
  87.             status = PrNewHandle(&aHandle, newSize);
  88.             nrequire(status, failed_Alloc);
  89.             
  90.             pGlobals = *hGlobals;            
  91.             workSpaceArray = (Handle*)((long)pGlobals + pGlobals->offsetToWorkspace);
  92.                                                                  
  93.             workSpaceArray[pGlobals->workSpaceIndex] = aHandle;
  94.             pGlobals->hWorkSpace = aHandle;
  95.             
  96.         } else {
  97.                                                                          
  98.             pGlobals->hWorkSpace = workSpaceArray[pGlobals->workSpaceIndex];
  99.             currSize = GetHandleSize(pGlobals->hWorkSpace);
  100.             
  101.             // Check to see if the workspace was purged, if it was allocate a new one.                
  102.             if ( *(pGlobals->hWorkSpace) == nil) {
  103.             
  104.                 ReallocateHandle(pGlobals->hWorkSpace, newSize);
  105.                 status = MemError();
  106.                 nrequire(status, failed_Realloc);
  107.                             
  108.             } else if (newSize > currSize) {
  109.             
  110.                 /** First try to grow, if grow fails, dispose and try to reallocate **/
  111.             
  112.                 status = PrSetHandleSize(pGlobals->hWorkSpace, newSize);
  113.                 if (status != noErr) {
  114.                                     
  115.                     pGlobals = *hGlobals;
  116.                     (void) DisposeHandle(pGlobals->hWorkSpace);
  117.                     nrequire(status = PrNewHandle(&aHandle, newSize), failed_SetSize);
  118.                     
  119.                     (*hGlobals)->hWorkSpace = aHandle;
  120.                                 
  121.                 } //end if
  122.                 nrequire(status, failed_SetSize);
  123.                         
  124.             }//end if
  125.             
  126.         }//end if
  127.                 
  128.         pGlobals = *hGlobals;
  129.         HNoPurge(pGlobals->hWorkSpace);                            // Make sure it isn't purged while in use.            
  130.  
  131.         /** Set up for next level of workspace if called recursively **/
  132.         ++(pGlobals->workSpaceIndex);
  133.  
  134.     
  135. failed_Realloc:
  136. failed_SetSize:
  137. failed_Alloc:
  138.         return(status);
  139.  
  140. /** Will exceed gsave limit due to recursive style **/
  141. workSpaceToDeep:
  142.         return(-999);
  143.     
  144.     }//PSSetWorkSpaceSize
  145.  
  146.  
  147.  
  148.  
  149.  
  150. //<FF>
  151. /***************************************************
  152.     Routine PSReleaseWorkSpace:
  153.     
  154.     Call this when done using the WorkSpace in a routine.
  155.     Unlock and mark the handle purgeable so we aren't piggy.
  156.     
  157.     hGlobals:        Handle to our globals.
  158.     
  159. ****************************************************/
  160.  
  161. OSErr PSReleaseWorkSpace(TIEGlobalsHdl hGlobals)
  162.     {
  163.         TIEGlobalsPtr        pGlobals;
  164.         OSErr                        status = noErr;
  165.         
  166.         pGlobals = *hGlobals;
  167.         
  168.                                                              
  169.         HUnlock(pGlobals->hWorkSpace);        // In case client left it locked.
  170.         HPurge(pGlobals->hWorkSpace);            // Mark it purgable, we don't want to be a pig.
  171.         
  172.         --(pGlobals->workSpaceIndex);            // Pop a workspace.
  173.  
  174. failed_SetSize:
  175.         return(status);
  176.     
  177.     }//PSReleaseWorkSpace
  178.  
  179.